#include "../include/fast.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "net.h"
#define mid 130//UA编号
#define ctoe_port 5555//防御控制器和防御执行器之间通信端口号
int sock;
int udp_flood=0,icmpv6_flood=0,alert=0;
int callback(struct fast_packet *pkt,int pkt_len);

int callback(struct fast_packet *pkt,int pkt_len)
{
	char drop=0;
	unsigned char tcp_type;
	unsigned char ip_src[16];
	unsigned char ip_dst[16];
  unsigned short type;//以太网帧类型
	unsigned char n;//next_head
	if(alert==1){
		unsigned char *p;
		p=pkt->data;
		p += 12;
		memcpy(&type, p, 2);
		type = ntohs(type);
		if(type == 0x86DD) {
			p += 2;
			p += 6;
			memcpy(&n, p, 1);
			p+=2;
			memcpy(ip_src,p,sizeof(ip_src));
      printf_ipv6(ip_src);
			p+=16;
			memcpy(ip_dst,p,sizeof(ip_dst));
      printf_ipv6(ip_dst);
			p+=16;
			while(n==0||n==60||n==43||n==44||n==51||n==50){
				p+=6;
				memcpy(&n,p,1);
				p+=34;
			}
      if(n==58){
		  	//icmpv6
        drop=1;
			}
			if(ip_cmp(ip_src,ip_dst)==1){
				drop=1;
			}
		}else{
      printf("type != 0x86DD\n");
      drop=1;
    }
	}

	if(drop==1){
		//pkt->um.discard=1;
		//printf("一条攻击流\n" );
		printf("-drop-");
	}

	if(drop==0){
		//printf("一条正常流\n" );
		printf("-normal-");
		pkt->um.dstmid=5;
		pkt->um.outport=1;
		pkt->um.pktdst=0;
		fast_ua_send(pkt,pkt_len);
	}

	return 0;
}
//ctrl+C停止操作前需要关闭socket，以及清零寄存器
void stop(int signo) {
  close(sock);
  if(fast_reg_rd(0x25800)!=0x0){
    fast_reg_wr(0x25800,0x0);
  }
  printf("已经关闭socket,寄存器已清零\n");
  exit(0);
}
int main(int argc,char* argv[]){
  int val;
  sock=get_server_socket(ctoe_port);
  if(sock < 0) {
  printf("can't get right socket\n");
    return -1;
  }
  printf("connect to server successfully!\n");

  /*初始化平台硬件*/
	fast_init_hw(0,0);
  //初始化寄存器，并打印寄存器值
  int flag=fast_reg_rd(0x25800);
  printf("初始寄存器值为：%x\n",flag);
  if(flag!=0x0){
    fast_reg_wr(0x25800,0x0);
  }
  //注册ctrl+C停止信号
  signal(SIGINT,stop);
  while(1){
    char atack_type;
    printf("wating for massages...\n");
    //接收防御控制器消息
		val = recv_msg(sock,&atack_type,1);
		if(val<=0){
			printf("recv_msg error\n");
			continue;
		}
		if(atack_type==0){//atack_type==0表示停止防御
			alert=0;
			udp_flood=0;
			icmpv6_flood=0;
      printf("get alert cancel\n");
      if(fast_reg_rd(0x25800)!=0x0){//避免重复写入
        //写寄存器  TCP防御开关地址：0x25800  0x0为关闭
        fast_reg_wr(0x25800,0x0);
        printf("寄存器值：%x\n",fast_reg_rd(0x25800));
      }
			if(icmpv6_flood==1){
				fast_ua_destroy();
				icmpv6_flood=0;
			}
		}else{//atack_type不为0 表示有攻击
      printf("get atack_type!!\n");
			alert=1;
			if(atack_type&1){//提取到tcp_flood
        printf("---tcp_flood");
        if(fast_reg_rd(0x25800)!=0x1){//避免重复写入
          //写寄存器  TCP防御开关地址：0x25800   0x1为开启
          sleep(5);
          fast_reg_wr(0x25800,0x1);
          printf("寄存器值：%x\n",fast_reg_rd(0x25800));
        }
			}
			if(atack_type&2){
        printf("---udp_flood");
        // fast_ua_init(mid,callback);
        // fast_ua_recv();
				udp_flood=1;//提取到udp_flood
			}
			if(atack_type&4){
        printf("---icmpv6_flood");
        fast_ua_init(mid,callback);
        fast_ua_recv();
				icmpv6_flood=1;//提取到icmpv6_flood
			}
			printf("\n");
		}
  }
  close(sock);
  return 0;
}
